package me.zhengjie.weixin;

import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.AmountReq;
import com.wechat.pay.java.service.refund.model.CreateRequest;
import com.wechat.pay.java.service.refund.model.Refund;
import me.zhengjie.config.WechatPayConfig;
import me.zhengjie.utils.OrderNoGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class WxRefundUtil {
    // 定义常量：货币类型为人民币（CNY）
    private static final String CURRENCY = "CNY";

    // 微信退款服务
    public static RefundService service;

    private static final Logger logger = LoggerFactory.getLogger(WxRefundUtil.class);

    /**
     * 进行微信退款查询
     * @param wechatPayConfig  微信支付配置
     * @param outRefundNo     商户退款单号
     * @param subMchid         子商户号
     * @param transactionId    微信订单号
     * @param reason           退款原因
     * @param amount           退款金额（单位：分）
     * @param total            原支付交易的订单总金额（单位：分）
     * @return Refund         退款结果
     */
    public static Refund refundQuery(WechatPayConfig wechatPayConfig,String outRefundNo, String subMchid, String transactionId,
                                     String reason, Long amount, Long total) {


        // 获取退款结果通知回调地址
        String refundNotifyUrl = wechatPayConfig.getRefundNotifyUrl();

        // 获取微信支付的配置
        Config config = wechatPayConfig.getNotificationConfig();

        // 初始化退款服务
        if (service == null) {
            logger.info("初始化微信退款服务...");
            service = new RefundService.Builder()
                    .config(config)
                    .build();
        }

        try {
            // 发起退款请求并返回退款结果
            Refund response = create(subMchid, transactionId, outRefundNo, reason, refundNotifyUrl, amount, total, CURRENCY);
            logger.info("退款请求成功，退款状态：{}", response);
            return response;
        } catch (Exception e) {
            // 异常捕获并记录日志
            logger.error("发起退款请求失败，出现未知错误。微信订单号：{}，退款金额：{}，失败原因：{}",
                    transactionId, amount, e.getMessage(), e);
            // 将异常抛出，便于外层调用捕获
            throw new RuntimeException("发起退款请求失败", e);
        }
    }

    /**
     * 发起退款申请
     * @param subMchid        子商户号
     * @param transactionId   微信订单号
     * @param outRefundNo     商户退款单号
     * @param reason          退款原因
     * @param refundNotifyUrl 退款结果通知URL
     * @param amount          退款金额（单位：分）
     * @param total           原支付交易的订单总金额（单位：分）
     * @param currency        货币类型，默认“CNY”
     * @return Refund        退款结果
     */
    private static Refund create(String subMchid, String transactionId, String outRefundNo, String reason,
                                String refundNotifyUrl, Long amount, Long total, String currency) {
        logger.info("开始创建退款请求：子商户号：{}，微信订单号：{}，商户退款单号：{}", subMchid, transactionId, outRefundNo);

        // 创建退款请求对象
        CreateRequest request = new CreateRequest();
        request.setSubMchid(subMchid);                  // 设置子商户号
        request.setTransactionId(transactionId);       // 设置微信订单号
        request.setOutRefundNo(outRefundNo);           // 设置商户退款单号
        request.setReason(reason);                     // 设置退款原因
        request.setNotifyUrl(refundNotifyUrl);         // 设置退款结果通知URL

        // 设置退款金额信息
        AmountReq amountReq = new AmountReq();
        amountReq.setTotal(total);         // 设置原支付交易的订单总金额
        amountReq.setRefund(amount);       // 设置退款金额
        amountReq.setCurrency(currency);   // 设置货币类型
        request.setAmount(amountReq);

        try {
            // 调用退款服务接口发起退款
            Refund response = service.create(request);
            logger.info("退款申请成功，退款结果：{}", response);
            return response;
        } catch (Exception e) {
            // 捕获并记录退款失败的详细信息
            logger.error("退款申请失败，子商户号：{}，微信订单号：{}，退款金额：{}，失败原因：{}",
                    subMchid, transactionId, amount, e.getMessage(), e);
            throw new RuntimeException("退款申请失败", e);
        }
    }
}
